day50

您所在的位置:网站首页 pagehelper多表分页 没出现table_count day50

day50

2023-06-11 09:43| 来源: 网络整理| 查看: 265

今日内容

0 复习昨日 一、分页插件 二、ORM映射【重点】 三、多表联查 【重点】 四、动态SQL 【重点】 五、$和#

零、复习昨日

mybatis orm框架,作用于持久层,高效开发,只关注sql,其他不用关心 思考MyBatis到底帮你省了哪些事情? jdbc第四步sql自己编写之外,其他mybatis都做了… 接口文件和映射文件如何关联? namespace 接口文件中方法又是如何和映射文件中的语句关联? 接口的方法名与映射文件标签的id一致 语句执行时入参都可以有哪些?有什么注意事项? 基本类型,String,Map,List,POJO(javabean/对象) 语句执行后返回的有哪些类型?(出参) 基本类型,字符串,对象

BUG: 1 idea中resuorces和test文件不识别

手动设置标记

image-20230607092633522

2 编码格式

控制台错误提示:

MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。

解决方案,在pom文件中加入配置

UTF-8 补充: mapper文件位置

mapper映射文件放置位置有两个

resources(推荐)java 如果使用这种,还需再pom文件加入build设置,让idea加载java下的xml文件

myabtis-config.xml文件加载映射文件时也要两种方案

使用 但是这种写法,会随着项目模块的增多,这个地方也会随之配置增多

使用

这种写法可以一次加载一个包下的所有映射文件,但是包结构要与接口文件包结构一致

总结,以后就按照以下写法配置:

映射文件全部放在resourcesresources下放映射文件包结构要与java放接口文件包结构一致文件名要一致 一、分页插件

现在我们要学习使用一个常用的mybatis的插件 --> 分页插件-PageHelper

最早: findAll() ---> 查全部 后来要分页: findAll(pageNo,pageSize) ---> 改动SQL 加上 limit x,y 还行count(*)来计数

使用分页插件之后,只编写正常的查询SQL即可,关于分页的操作插件会自动完成.

引入依赖

com.github.pagehelper pagehelper 5.3.0

全局配置文件使用插件

在查询时使用分页功能

public interface UserMapper { List findAll(); } select * from tb_user @Test public void findAll() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 【在执行查询前设置】 // 参数1: 当前页 // 参数2: 每页大小 PageHelper.startPage(2,2); List all = mapper.findAll( ); for (User user : all) { System.out.println(user ); } }

image-20221215152540842

mybatis插件是对运行时某一点进行拦截

pagehelper插件是拦截运行时发出的SQL,自动在SQL后面拼接关键词

后续还可以获得更新消息的分页数据,比如共多少条数据?共多少页?当前页?下一页?目前是不是第一页?

@Test public void findAll() { UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 【在执行查询前设置】 // 参数1: 当前页 // 参数2: 每页大小 PageHelper.startPage(2,2); // 执行查询全部 List userList = mapper.findAll( ); // 后续可以获得更详细的信息 PageInfo pageInfo = new PageInfo(userList); System.out.println(pageInfo ); // 获得总条数 System.out.println(pageInfo.getTotal() ); // 获得总页数 System.out.println(pageInfo.getPages() ); // 获得总数据(当前页中的总数据) System.out.println(pageInfo.getList() ); }

ps: 可以看源码,中国人开发,注释非常好理解

二、ORM映射 2.1 MyBatis自动ORM失效

MyBatis只能自动维护库表”列名“与”属性名“相同时的一一对应关系,二者不同时,无法自动ORM。

自动ORM失效image-20230601164912980 2.2 方案一:列的别名

在SQL中使用 as 为查询字段添加列别名,以匹配属性名。

select id as idd,username,password,phone,create_time,sex,money from tb_user where id = #{id} 2.3 方案二:结果映射(ResultMap - 查询结果的封装规则)

通过< resultMap id=“” type=“” >映射,匹配列名与属性名。

select id,username,password,phone,create_time,sex,money from tb_user where id = #{id} 三、 多表联查 【重点】

表关系: 一对一,一对多,多对多

多表联查的SQL

3.1 OneToOne

需求: 实现一对一查询,查询订单以及对应的用户信息

数据: tb_user表, tb_order表

关系:

用户 —> 订单 (1 VS N) 一个用户有多个订单 订单 —> 用户 (1 VS 1) 一个订单只会属于一个人

tb_user表

CREATE TABLE `tb_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号', `username` varchar(10) DEFAULT NULL COMMENT '用户名', `password` varchar(10) DEFAULT NULL COMMENT '密码', `phone` varchar(11) DEFAULT NULL COMMENT '手机号', `create_time` date DEFAULT NULL COMMENT '注册时间', `money` double(10,2) DEFAULT NULL COMMENT '账户余额' PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8;

tb_order表

CREATE TABLE `tb_order` ( `oid` int(11) NOT NULL AUTO_INCREMENT COMMENT '订单编号', `order_time` datetime DEFAULT NULL COMMENT '订单时间', `order_desc` varchar(255) DEFAULT NULL COMMENT '订单详情', `uid` int(11) DEFAULT NULL COMMENT '关联用户id', PRIMARY KEY (`oid`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `tb_order` VALUES (1, '2022-11-17 15:06:29', '笔记本电脑', 1); INSERT INTO `tb_order` VALUES (2, '2022-12-16 11:00:41', 'Cherry键盘', 1); INSERT INTO `tb_order` VALUES (3, '2022-12-16 11:01:23', 'Logi鼠标', 2);

实体类

public class Order { private int oid; private Date orderTime; private String orderDesc; private int uid; // set get... }

但是上面的实体类,只有订单信息,我们要查询的是订单和用户! 上面的类就无法展现全部数据,所以需要扩展类

public class OrderVO extends Order { private User user; // set get }

OrderMapper.java接口文件

public interface OrderMapper { OrderVO findOrderWithUserById(int oid); }

OrderMapper.xml映射文件

SELECT o.*, u.* FROM tb_order o, tb_user u WHERE o.uid = u.id AND o.oid = 1

测试

@Test public void findOrderWithUserById() { OrderMapper mapper = sqlSession.getMapper(OrderMapper.class); OrderVO orderVO = mapper.findOrderWithUserById(1); // 获得订单信息 int oid = orderVO.getOid( ); System.out.println("oid = " + oid); Date orderTime = orderVO.getOrderTime( ); System.out.println("orderTime = " + orderTime); String orderDesc = orderVO.getOrderDesc( ); System.out.println("orderDesc = " + orderDesc); // 获得订单一家关联的用户信息 User user = orderVO.getUser( ); System.out.println(user ); } 3.2 OneToMore

需求: 一对多,查询用户关联查询出所有的订单

SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = 3

目的查询用户,以及关联多个订单,User类不够展现全部数据,那么就创建扩展类UserVO,UserVO类继承User就可以存储用户信息,还需要再UserVO类中添加Order类来存储信息,但是!!不是一个Order类,因为是一对多,一个用户关联多个订单,所有要设置List

User扩展实体类

public class UserVO extends User{ private List orderList; @Override public String toString() { String s = super.toString( ); return s +" \r\n UserVO{" + "orderList=" + orderList + '}'; } public List getOrderList() { return orderList; } public void setOrderList(List orderList) { this.orderList = orderList; } }

UserMapper.java接口

public interface UserMapper { UserVO findUserWithOrdersById(int id); }

UserMapper.xml映射文件

SELECT * FROM tb_user u LEFT JOIN tb_order o ON u.id = o.uid WHERE u.id = #{id} 3.3 关联查询总结

正常封装使用resultMap

一对一封装使用association

一对多封装使用collection

四、动态SQL【重点】

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

自己话理解: 帮助我们拼接SQL

常见的动态SQL语法

SQL片段(官方不是在动态SQL章节)where , ifsettrimforeach 4.1 SQL片段

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。

自己的话: 减少代码重复,主要用于抽取字段,表名等

id, username, password, phone, create_time, money, sex select from tb_user 4.2 if

if就是用来判断,主要用于判断要不要拼接对应的条件语句

-- 需求:查询用户,条件是money=1000,如果密码不为空,也根据密码查 select * from tb_user where money = 1000 select * from tb_user where money = 1000 and password= '123456'

UserMapper.java接口方法

public interface UserMapper { /** * 演示if动态sql */ List findByMap(HashMap map); }

UserMapper.xml

select from tb_user where money = #{money} and password = #{password}

测试

/** * if动态sql */ @Test public void showIf() { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); HashMap map = new HashMap( ); map.put("money",1000); List list = userMapper.findByMap(map); for (User user : list) { System.out.println(user ); } } 4.3 where

如果说只有if,可能会出现这么一种情况

SELECT * FROM tb_user WHERE

多出一个where关键词!!

所以我们需要一个智能的,有条件时帮我们拼接where关键词,没有条件查询时,不拼接where

select from tb_user sex = #{sex}

所以一般会where和if一起用

4.4 set

用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。

UserMapper.java接口方法

public interface UserMapper { int updateUser(User user); }

UserMapper.xml

update tb_user username = #{username}, password = #{password}, phone = #{phone}, create_time = #{createTime}, money = #{money}, sex = #{sex}, where id = #{id}

测试

@Test public void testUpdate(){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User( ); user.setId(1); // 只更新这个2字段,其他字段不动 user.setUsername("QF"); user.setPassword("qf666"); int i = mapper.updateUser(user); System.out.println(i > 0?"OK":"ERR" ); // 增删改要提交 sqlSession.commit(); } 4.5 foreach

场景: 批量删除

delete from tb_user where id in (1,2,3,...); String sql = "delete from tb_user where id in ("; int iMax = idsArr.length - 1;// 最大下标 for (int i = 0; i sql += ","; } else { sql += ")"; } }

UserMapper.java

public interface UserMapper { // 为了演示动态sql foreach int deleteBatch(List ids); }

UserMapper.xml

delete from tb_user where id in #{id}

测试

/** * 测试foreach */ @Test public void testForeach(){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); ArrayList list = new ArrayList( ); list.add(31); list.add(32); list.add(33); int i = mapper.deleteBatch(list); System.out.println("i = " + i); System.out.println(i > 0?"OK":"ERR" ); // 增删改要提交 sqlSession.commit(); } 任务 使用项目中的表,重复1遍 合同加房屋实现多表联查 做笔记,写注释,画图标记 使用项目中的表,重复1遍 合同加房屋实现多表联查 做笔记,写注释,画图标记


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3